﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net.Sockets;
using System.Threading;
using System.Net;

using System.IO;

namespace readnumber
{
    public class network
    {
        private TcpListener tcpListener;
        private Thread listenThread;
        private TcpClient tcpClient;
        Form1 f1;

        public network()
        {
            
        }

        public void createConnection(int port, Form1 form)
        {
            this.f1 = form;
            if (this.listenThread == null || !this.listenThread.IsAlive)
            {
                this.tcpListener = new TcpListener(IPAddress.Any, port);
                this.listenThread = new Thread(new ThreadStart(ListenForClients));
                this.listenThread.Start();
            }
        }
        
        public void closeConnection()
        {
            this.tcpListener.Stop();
            if(this.tcpClient != null) this.tcpClient.Close();
        }

        public List<String> getIP()
        {
            List<String> ipList = new List<string>();
            IPAddress[] ipAdd = Dns.GetHostAddresses(Dns.GetHostName());
            for (int i = 0; i < ipAdd.Length; i++)
            {
                if (ipAdd[i].AddressFamily == AddressFamily.InterNetwork)
                {
                    ipList.Add(ipAdd[i].ToString());
                }
            }
            return ipList;
        }

        private void ListenForClients()
        {
            this.tcpListener.Start();

            while (true)
            {
                //blocks until a client has connected to the server
                try
                {
                    TcpClient client = this.tcpListener.AcceptTcpClient();
                    //create a thread to handle communication 
                    //with connected client
                    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                    clientThread.Start(client);
                }
                catch (Exception e)
                {
                    break;
                }                
            }
        }

        private void HandleClientComm(object client)
        {
            tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();
            System.Text.Encoding enc = System.Text.Encoding.ASCII;

            FileStream fileImage = null;

            byte[] message = new byte[4096];
            int bytesRead;
            int iMessageType = 0;

            while (true)
            {
                bytesRead = 0;

                try
                {
                    //blocks until a client sends a message
                    bytesRead = clientStream.Read(message, 0, 4096);
                    if(!clientStream.DataAvailable && bytesRead == 8)
                    {
                        String sMsg = enc.GetString(message, 0, bytesRead);
                        if (sMsg.Trim() == "[connec]") 
                        { 
                            byte[] outMsg = new byte[8];
                            outMsg[0] = (byte)'r';//rn101 - readnumber version 1.01
                            outMsg[1] = (byte)'n';
                            outMsg[2] = (byte)'1';
                            outMsg[3] = (byte)'0';
                            outMsg[4] = (byte)'1';
                            outMsg[5] = outMsg[6] = outMsg[7] = 0;
                            clientStream.Write(outMsg, 0, 8);
                        }
                        else if (sMsg == "[imagex]")
                        {
                            iMessageType = 1;
                            try
                            {
                                fileImage = File.Open("image.jpg", FileMode.Create, FileAccess.Write, FileShare.Read);
                            }
                            catch (Exception e)
                            {
                                MessageBox.Show("ERROR: Unable to open image!\n" + e.Message);
                            }
                        }
                        else
                        {
                            iMessageType = 0;
                        }
                    }
                    else if(bytesRead>0)
                    {
                        if (iMessageType == 1)
                        {
                            if (fileImage != null) fileImage.Write(message, 0, bytesRead);
                        }
                        else
                        {
                            f1.SetText(enc.GetString(message, 0, bytesRead));
                        }
                    }
                }
                catch
                {
                    //a socket error has occured
                    break;
                }

                if (bytesRead == 0)
                {
                    break;
                }
                bytesRead = 0;

                //message has successfully been received
                ASCIIEncoding encoder = new ASCIIEncoding();
                System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
            }

            //the client has disconnected from the server
            if (fileImage != null)
            {
                fileImage.Close();
                fileImage = null;
                Application.DoEvents();
                f1.imageTransmitted();
            }

            tcpClient.Close();
        }
    }
}
